package com.san.metadata.service.impl;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.san.common.utils.CTConversionUtils;
import com.san.common.utils.Constant;
import com.san.common.utils.ExcelUtil;
import com.san.metadata.dao.DataImportManager;
import com.san.metadata.domain.DataImportDTO;
import com.san.metadata.domain.TechnicalColumnsDO;
import com.san.metadata.domain.TechnicalTableDO;
import com.san.metadata.service.DataImportService;
import com.san.metadata.service.TechnicalMetadataService;
import com.san.oa.service.NotifyService;
import com.san.oa.vo.NotifyVO;

@Service
public class DataImportServiceImpl implements DataImportService {

	@Autowired
	private TechnicalMetadataService technicalService;

	@Autowired
	private DataImportManager dataImportManager;

	@Autowired
	private NotifyService notifyService;

	@Override
	public void doImport(DataImportDTO dataImportDTO) throws Exception {
		MultipartFile file = dataImportDTO.getFile();
		if (null == file || file.isEmpty()) {
			return;
		}
		// 上传文件名称
		String oldFileName = file.getOriginalFilename();
		// 文件类型-后缀
		String fileType = oldFileName.substring(oldFileName.lastIndexOf(".") + 1);
		List<List<String>> list = null;

		list = ExcelUtil.read(file.getInputStream(), fileType, true);

		if (null == list || list.size() <= 0) {
			return;
		}

		TechnicalTableDO technicalTableDO = technicalService.getById(dataImportDTO.getTableId());

		Map<String, Object> result = this.checkTitle(dataImportDTO.getTableId(), list.get(0));
		if (Constant.RESULT_CODE_SUCESS == (Integer) result.get("result_code")) {

			List<List<String>> errorList = dataImportManager.batchSave(technicalTableDO, result, list);

			String resultMsg = "本次上传结果：上传总数为" + (list.size() - 1);
			if (errorList.size() > 0) {
				resultMsg += "，失败条数为" + (errorList.size() - 1) + "，错误数据请下载附件查看";
			} else {
				resultMsg += "，失败条数为 0";
			}

			this.saveNotify(dataImportDTO.getUserId(), dataImportDTO.getBatchNo(), resultMsg,
					technicalTableDO.getTargetTableName(), errorList);
		} else {
			String resultMsg = "导入失败" + result.get("result_msg");
			this.saveNotify(dataImportDTO.getUserId(), dataImportDTO.getBatchNo(), resultMsg,
					technicalTableDO.getTargetTableName(), new ArrayList<List<String>>());
		}
	}

	/**
	 * 检查标题，并解析必要信息
	 * 
	 * @param tableId
	 * @param title
	 * @return
	 * @throws Exception
	 */
	private Map<String, Object> checkTitle(Long tableId, List<String> title) throws Exception {
		// 返回信息
		Map<String, Object> result = new HashMap<String, Object>();
		// 时间字段下标
		List<Integer> dateColumnList = new ArrayList<Integer>();
		StringBuffer columns = new StringBuffer();
		List<TechnicalColumnsDO> listColumn = technicalService.allTechnicalColumns(tableId);
		if (listColumn.size()-1 != title.size()) {
			result.put("result_code", Constant.RESULT_CODE_ERROR);
			result.put("result_msg", "导入字段数量与实际不匹配");
		} else {
			int autoInputDateIndex = 0;
			int index = 0;
			for (TechnicalColumnsDO technicalColumnsDO : listColumn) {
				if (Constant.NDATA_IMPORT_AUTO_INPUT_DATE.equals(technicalColumnsDO.getColumnName())) {
					autoInputDateIndex = index;
				} else {
					if (!technicalColumnsDO.getColumnComment().toUpperCase().equals(title.get(index).toUpperCase())) {
						result.put("result_code", Constant.RESULT_CODE_ERROR);
						result.put("result_msg", "导入字段描述有误或顺序与实际不匹配");
						return result;
					}
					if (CTConversionUtils.isDateColumn(technicalColumnsDO.getColumnType())) {
						dateColumnList.add(index);
					}
					index ++;
				}
				columns.append(technicalColumnsDO.getColumnName());
				columns.append(",");
			}
			result.put("result_code", Constant.RESULT_CODE_SUCESS);
			result.put("columns", columns.substring(0,columns.length()-1));
			result.put("columnSize", listColumn.size());
			result.put("autoInputDateIndex", autoInputDateIndex);
		}
		result.put("dateColumnList", dateColumnList);
		return result;
	}

	/**
	 * 保存数据导入系统通知
	 * 
	 * @param userId
	 * @param batchNo
	 * @param resultMsg
	 * @param tableName
	 * @param errorList
	 * @throws Exception
	 */
	public void saveNotify(long userId, String batchNo, String resultMsg, String tableName,
			List<List<String>> errorList) throws Exception {
		NotifyVO notifyVO = new NotifyVO();
		notifyVO.setCreateUserId(new Long(100000));

		notifyVO.setContent(resultMsg);
		notifyVO.setTitle("数据导入结果通知");
		notifyVO.setDelFlag(Constant.DEL_FLAG_NORMAL);
		notifyVO.setCreateDate(new Date());
		notifyVO.setUserIds(new Long[] { userId });
		notifyVO.setStatus(Constant.OA_NOTIFY_STATUS_PUBLISH);
		notifyVO.setType(Constant.OA_NOTIFY_TYPE_SYSTEM);
		notifyVO.setRemarks("系统通知");

		// 存在错误数据
		if (errorList.size() > 0) {
			StringBuffer path = new StringBuffer(notifyService.buildPath(Constant.NOTIFY_PATH_DATA_IMPORT));
			// 新文件名
			String newFileName = "数据导入错误数据反馈_" + batchNo + "_" + tableName + ".xlsx";
			notifyVO.setFilePath(path + newFileName);

			XSSFWorkbook workbook = new XSSFWorkbook();
			XSSFSheet sheet = workbook.createSheet();

			// 创建第一行
			XSSFRow row = null;
			XSSFCell cell = null;
			for (int i = 0; i < errorList.size(); i++) {
				List<String> values = errorList.get(i);
				row = sheet.createRow(i);

				for (int j = 0; j < values.size(); j++) {
					cell = row.createCell(j);
					// 设置单元格值
					ExcelUtil.setValue(cell, values.get(j));
					// 设置单元格宽度
					ExcelUtil.setWidth(sheet, cell);
				}
			}

			OutputStream os = new FileOutputStream(notifyVO.getFilePath());
			workbook.write(os);
			os.close();
			workbook.close();
		}

		notifyService.save(notifyVO);
	}
}
